package com.czxy.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;
import tk.mybatis.mapper.entity.Config;
import tk.mybatis.mapper.mapperhelper.MapperHelper;

import java.io.InputStream;

public class MyBatisUtils {
	
	// 会话工厂
	private static SqlSessionFactory factory;
	static{
		try {
			// 1.1 加载核心配置文件
			InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
			// 1.2 获得工厂
			factory = new SqlSessionFactoryBuilder().build(is);
			
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	private static ThreadLocal<SqlSession> local = new ThreadLocal<>();
	
	/**
	 * 获得新会话
	 * @return
	 */
	private static SqlSession openSession(){
		SqlSession sqlSession = local.get();
		if(sqlSession == null){
			sqlSession = factory.openSession();

			//创建一个MapperHelper
			MapperHelper mapperHelper = new MapperHelper();
			//特殊配置
			Config config = new Config();
			// 支持方法上的注解
			// 3.3.1版本增加
			config.setEnableMethodAnnotation(true);
			config.setNotEmpty(true);
			//设置配置
			mapperHelper.setConfig(config);
			// 注册通用Mapper接口 - 可以自动注册继承的接口
			mapperHelper.registerMapper(Mapper.class);
			mapperHelper.registerMapper(MySqlMapper.class);
			//配置完成后，执行下面的操作
			mapperHelper.processConfiguration(sqlSession.getConfiguration());

			local.set(sqlSession);
		}
		return sqlSession;
	}
	
	/**
	 * 获得mapper
	 * @param clazz
	 * @return
	 */
	public static <T> T getMapper(Class<T> clazz){
		return openSession().getMapper(clazz);
	}
	
	/**
	 * 释放资源
	 */
	public static void close() {
		SqlSession sqlSession = openSession();
		if(sqlSession != null){
			sqlSession.close();
			local.remove();
		}
	}

	/**
	 * 提交并释放资源
	 * @param 
	 */
	public static void commitAndClose() {
		SqlSession sqlSession = openSession();
		if(sqlSession != null){
			sqlSession.commit();
			close();
		}
	}
	
	/**
	 * 回滚并释放资源
	 * @param 
	 */
	public static void rollbackAndClose() {
		SqlSession sqlSession = openSession();
		if(sqlSession != null){
			sqlSession.rollback();
			close();
		}
	}

}